package com.suning.sawp.service.impl.oga;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.suning.framework.dal.client.DalClient;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.po.customer.AOGBean;
import com.suning.sawp.po.customer.ActStaffRel;
import com.suning.sawp.po.customer.ClerkOutAddrBean;
import com.suning.sawp.po.customer.LastSelEmpBean;
import com.suning.sawp.po.customer.OutAddrBean;

/**
 * 
 * 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 12061748
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class OgaService {

    private static final int LAST_SEL_EMP_LIMIT = 50;
    private static final Logger LOGGER = LoggerFactory.getLogger(OgaService.class);
    @Resource
    DalClient dalClient;

    /**
     * 
     * 功能描述:查询活动 <br>
     * 〈功能详细描述〉
     *
     * @param storeCode
     * @param staffCode
     * @param positionId
     * @param queryType
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<AOGBean> queryOutGrowActList(String storeCode, String staffCode, String positionId, String queryType) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("queryType", queryType);
        map.put("storeCode", storeCode);
        map.put("staffCode", staffCode);
        // 店长和督导直接查询门店外拓活动表
        if (StringUtils.isNotBlank(positionId)
                && (ClerkConstants.STORE_KEEPER.equals(positionId) || ClerkConstants.SALE_GUIDE.equals(positionId))) {
            return dalClient.queryForList("outGrow.queryOutGrowActList", map, AOGBean.class);
        }
        // 店员查询店员活动表关联表查询活动记录
        return dalClient.queryForList("outGrow.queryClerkOutGrowActList", map, AOGBean.class);
    }

    /**
     * 
     * 功能描述:通过活动id查询下面可见的任务列表 <br>
     * 〈功能详细描述〉
     *
     * @param storeCode
     * @param staffCode
     * @param positionId
     * @param queryType
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<OutAddrBean> queryOutAddrTaskList(String storeCode, String staffCode, String positionId, String actId) {
        List<OutAddrBean> list = null;
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("staffCode", staffCode);
        map.put("actId", actId);
        map.put("storeCode", storeCode);
        // 店长能看到所有门店任务
        if (ClerkConstants.STORE_KEEPER.equals(positionId)) {
            list = dalClient.queryForList("outGrow.queryKeeperTaskList", map, OutAddrBean.class);
        } else if (ClerkConstants.SALE_GUIDE.equals(positionId)) {
            // 督导能看到他创建+分给他的门店任务详情
            map.put("staffCode", staffCode);
            list = dalClient.queryForList("outGrow.queryGuideTaskList", map, OutAddrBean.class);
        } else {
            // 店员只能看到分给他的
            list = dalClient.queryForList("outGrow.queryClerkTaskList", map, OutAddrBean.class);
        }
        return list;
    }

    /**
     * 
     * 功能描述: 查询本月已创建活动数量<br>
     * 〈功能详细描述〉
     *
     * @param staffCode
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public long countThisMonthCreateActNum(String storeCode) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("storeCode", storeCode);
        Map<String, Object> result = dalClient.queryForMap("outGrow.countThisMonthCreateActNum", map);
        return (Long) result.get("num");
    }

    /**
     * 
     * 功能描述:查询活动下门店地点任务数量 <br>
     * 〈功能详细描述〉
     *
     * @param actId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public long countOutAddrNumByActId(Long actId, String storeCode) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("actId", actId);
        map.put("storeCode", storeCode);
        Map<String, Object> result = dalClient.queryForMap("outGrow.countOutAddrNumByActId", map);
        return (Long) result.get("num");
    }

    /**
     * 
     * 功能描述:保存外拓活动信息 <br>
     * 〈功能详细描述〉
     *
     * @param bean
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public Long createOutGrowAct(AOGBean bean) {
        return (Long) dalClient.persist(bean);
    }

    /**
     * 
     * 功能描述:修改外拓活动信息 <br>
     * 〈功能详细描述〉
     *
     * @param bean
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void updateOutGrowAct(AOGBean bean) {
        dalClient.dynamicMerge(bean);
    }

    /**
     * 
     * 功能描述:修改外拓活动信息 <br>
     * 〈功能详细描述〉
     *
     * @param bean
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<ActStaffRel> queryActStaffRelList(long actId) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("actId", actId);
        return dalClient.queryForList("outGrow.queryActStaffRelList", map, ActStaffRel.class);
    }

    /**
     * 
     * 功能描述:保存人员和活动关系表 <br>
     * 〈功能详细描述〉
     *
     * @param bean
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void saveActStaffRelInfo(ActStaffRel actStaffRel) {
        dalClient.persist(actStaffRel);
    }

    /**
     * 
     * 功能描述:创建和修改门店外拓地点任务表<br>
     * 〈功能详细描述〉
     *
     * @param bean
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @Transactional
    public void saveOutAddrTask(OutAddrBean bean) {
        bean.setStartTime(bean.getStartTime() + " 00:00:00");
        bean.setEndTime(bean.getEndTime() + " 23:59:59");
        List<ClerkOutAddrBean> clerkTasks = bean.getClerkOutAddrTasks();

        /**
         * 非新增场景查询活动人员对应表 获取当前活动下的人员集合
         */
        List<ActStaffRel> relList = null;
        if (bean.getActId() != null) {
            relList = queryActStaffRelList(bean.getActId());
        }
        /**
         * 1.保存门店任务信息
         */
        List<LastSelEmpBean> lastSelList = new ArrayList<LastSelEmpBean>();
        if (bean.getTaskId() == null) {
            bean.setCompNum(0);
            long taskId = (Long) dalClient.persist(bean);
            /**
             * 2.分配到店员创建任务信息
             */
            for (ClerkOutAddrBean clerkOutAddr : clerkTasks) {
                clerkOutAddr.setParTaskId(taskId);
                clerkOutAddr.setCompNum(0);
                clerkOutAddr.setStoreCode(bean.getStoreCode());
                clerkOutAddr.setActId(bean.getActId());
                dalClient.persist(clerkOutAddr);
                /**
                 * 3.维护保存到活动和店员对应关系表
                 */
                maintainActRelStaff(relList, clerkOutAddr, bean.getActId());
                /**
                 * 组装最近选择人对象
                 */
                LastSelEmpBean lse = new LastSelEmpBean();
                lse.setStaffCode(clerkOutAddr.getStaffCode());
                lse.setStaffName(clerkOutAddr.getStaffName());
                lse.setRelCode(bean.getStaffCode());
                lastSelList.add(lse);
            }
        } else {
            bean.setCompNum(null);
            dalClient.dynamicMerge(bean);
            /**
             * 2.分配到店员创建任务信息
             */
            for (ClerkOutAddrBean clerkOutAddr : clerkTasks) {
                if (clerkOutAddr.getTaskId() == null) {
                    // 之前不存在的人则创建人员任务
                    clerkOutAddr.setParTaskId(bean.getTaskId());
                    clerkOutAddr.setCompNum(0);
                    clerkOutAddr.setStoreCode(bean.getStoreCode());
                    clerkOutAddr.setActId(bean.getActId());
                    dalClient.persist(clerkOutAddr);
                    /**
                     * 3.维护保存到活动和店员对应关系表
                     */
                    maintainActRelStaff(relList, clerkOutAddr, bean.getActId());
                } else {
                    // 之前存在的数据则更新操作
                    clerkOutAddr.setCompNum(null);
                    // 此方法不会覆盖null值字段
                    dalClient.dynamicMerge(clerkOutAddr);
                }
                /**
                 * 组装最近选择人对象
                 */
                LastSelEmpBean lse = new LastSelEmpBean();
                lse.setStaffCode(clerkOutAddr.getStaffCode());
                lse.setStaffName(clerkOutAddr.getStaffName());
                lse.setRelCode(bean.getStaffCode());
                lastSelList.add(lse);
            }
        }
        /**
         * 4.维护最近选择人（最多50个）
         */
        maintainLastSelEmp(lastSelList, bean.getStaffCode());
    }

    /**
     * 
     * 功能描述:维护活动和人员关系表 <br>
     * 〈功能详细描述〉
     *
     * @param relList
     * @param clerkOutAddr
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private void maintainActRelStaff(List<ActStaffRel> relList, ClerkOutAddrBean clerkOutAddr, long actId) {
        Boolean isExsit = false;
        if (CollectionUtils.isNotEmpty(relList)) {
            for (ActStaffRel rel : relList) {
                if (rel.getStaffCode().equals(clerkOutAddr.getStaffCode())) {
                    isExsit = true;
                    break;
                }
            }
        }
        if (!isExsit) {
            ActStaffRel actStaffRel = new ActStaffRel();
            actStaffRel.setActId(actId);
            actStaffRel.setStaffCode(clerkOutAddr.getStaffCode());
            saveActStaffRelInfo(actStaffRel);
        }
    }

    /**
     * 
     * 功能描述:维护活动和人员关系表 <br>
     * 〈功能详细描述〉
     *
     * @param relList
     * @param clerkOutAddr
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public void maintainLastSelEmp(List<LastSelEmpBean> lastSelEmpList, String relCode) {
        /**
         * 1.先全部入库
         */
        if (CollectionUtils.isNotEmpty(lastSelEmpList)) {
            // 插入客户端传过来的最近联系人，没有记录则新增操作，有则更新数据
            List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
            for (LastSelEmpBean dto : lastSelEmpList) {
                Map<String, Object> paramMap = new HashMap<String, Object>();
                paramMap.put("relCode", relCode);
                paramMap.put("staffName", dto.getStaffName());
                paramMap.put("staffCode", dto.getStaffCode());
                mapList.add(paramMap);
            }
            @SuppressWarnings("unchecked")
            Map<String, Object>[] batchValues = (Map<String, Object>[]) mapList.toArray(new Map[mapList.size()]);
            try {
                // 批量更新插入操作
                dalClient.batchUpdate("outGrow.upsertLastSelEmpInfo", batchValues);
            } catch (Exception e) {
                LOGGER.error("OgaService.maintainLastSelEmp upsertLastSelEmpInfo error", e);
            }

        }
        /**
         * 2.删除大于50个的，通过更新时间筛选时间最早的删除掉
         */
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("relCode", relCode);
        paramMap.put("limit", LAST_SEL_EMP_LIMIT);
        // 查找index = limit 的选择人的数据
        LastSelEmpBean limitSelBean = dalClient.queryForObject("outGrow.queryLimitSelEmp", paramMap,
                LastSelEmpBean.class);
        if (null != limitSelBean) {
            // 删除超出50的时间最早的选择联系人;
            paramMap.put("updateTime", limitSelBean.getUpdateTime());
            dalClient.execute("outGrow.removeOverLimitSelEmpList", paramMap);
        }

    }

    /**
     * 
     * 功能描述: 查询最近选择人<br>
     * 〈功能详细描述〉
     *
     * @param relCode
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<LastSelEmpBean> queryLastSelEmpList(String relCode) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("relCode", relCode);
        return dalClient.queryForList("outGrow.queryLastSelEmpList", map, LastSelEmpBean.class);
    }

    /**
     * 
     * 功能描述: 查询外拓地点任务完成详情<br>
     * 〈功能详细描述〉
     *
     * @param taskId
     * @param storeCode
     * @param staffCode
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public List<ClerkOutAddrBean> queryClerkTaskList(String taskId, String storeCode) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("taskId", taskId);
        map.put("storeCode", storeCode);
        return dalClient.queryForList("outGrow.queryAllClerkTaskList", map, ClerkOutAddrBean.class);
    }

    /**
     * 
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param taskId
     * @param storeCode
     * @param staffCode
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @Transactional
    public void incrCompltNum(long taskId, String storeCode, String staffCode) {
        // 门店地点任务表通过任务id和门店编码更新已完成人数+1
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("taskId", taskId);
        map.put("storeCode", storeCode);
        map.put("staffCode", staffCode);
        dalClient.execute("outGrow.updateStoreAddrComptNum", map);
        // 店员地点任务表通过门店任务id和门店编码和店员工号更新已完成人数+1
        dalClient.execute("outGrow.updateClerkAddrComptNum", map);
    }
}
